//======================================================================
/// COPYRIGHT MorningCoreTech CO.,LTD
/// @file        PUCCH_Spreading_fix.cpp
/// @brief       This function performs PUCCH Spreading Proc
/// @author      cuiyuping
/// @param [IN]	     SimParam		       Input  Parameter .
/// @param [IN]	     QAM_Op		           Modulation Data
/// @param [IN]	    PUCCH_ZC_Data		   DMRS Sequence.     
/// @param [OUT]	PUCCH_ResOp		       PUCCH Spreading Result.     
/// @par History
/// -
///       Date|       Author|        Version|        DESCRIPTION
/// ----------|-------------|---------------|-------------------
/// 2022-10-20|   cuiyuping |          0.0.1|            created
//======================================================================

#include "../../../CommLib_FxpC/lib_arith_N.h"
#include "../../../CommLib_FltC/GlobalVarDef.h"
#include "../common/head/NR_UL_macro.h"
#include "ue_tx_pucch_spreading_fix.h"


void PUCCH_Spreading_fix
(
    IN stULParamTable *SimParam,
    IN  cmplx_frN  *QAM_Op,             
    IN  cmplx_frN  *PUCCH_ZC_Data[PUCCH_DMRS_MAX_NUM], 
    OUT cmplx_frN  *PUCCH_ResOp[PUCCH_DATA_MAX_NUM]  
    )
{
    /*variables definition*/
	int k,l;
	fractN  *P_OVSF_Code;
	cmplx_frN   Temp;
	cmplx_frN   OVSF_Code;
	int8  DataSymSecondHop = 0;
	uint64 temp = 0;

    /*Init*/
	set_rnd_mode_floor();

	if (PUCCH_FORMAT_0 == SimParam->PUCCH_Format)
	{
		if (0 == SimParam->intra_slot_hopping)
		{
			P_OVSF_Code = NocSF_F0_Fix[SimParam->DataSymNum - 1][SimParam->F1_OCC_Index];
			for (l = 0; l < SimParam->DataSymNum; l++)//for each symbol of one slot
			{
				/*get OVSF code*/
				OVSF_Code.re = *P_OVSF_Code++;
				OVSF_Code.im = *P_OVSF_Code++;
				for (k = 0; k < SC_PER_RB; k++)
				{
					Temp.re = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].re - QAM_Op[0].im*PUCCH_ZC_Data[l][k].im) >> 1, 14);
					Temp.im = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].im + QAM_Op[0].im*PUCCH_ZC_Data[l][k].re) >> 1, 14);

					PUCCH_ResOp[l][k].re = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.re - Temp.im*OVSF_Code.im) >> 13, 14);
					PUCCH_ResOp[l][k].im = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.im + Temp.im*OVSF_Code.re) >> 13, 14);

				}
			}
		}
		else
		{
			P_OVSF_Code = NocSF_F0_Fix[SimParam->DataSymFirstHop - 1][SimParam->F1_OCC_Index];
			for (l = 0; l < SimParam->DataSymFirstHop; l++)//for each symbol of one slot
			{
				/*get OVSF code*/
				OVSF_Code.re = *P_OVSF_Code++;
				OVSF_Code.im = *P_OVSF_Code++;
				for (k = 0; k < SC_PER_RB; k++)
				{
					Temp.re = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].re - QAM_Op[0].im*PUCCH_ZC_Data[l][k].im) >> 1, 14);
					Temp.im = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].im + QAM_Op[0].im*PUCCH_ZC_Data[l][k].re) >> 1, 14);

					PUCCH_ResOp[l][k].re = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.re - Temp.im*OVSF_Code.im) >> 13, 14);
					PUCCH_ResOp[l][k].im = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.im + Temp.im*OVSF_Code.re) >> 13, 14);
				}

			}

			//second hopping
			DataSymSecondHop = SimParam->DataSymNum - SimParam->DataSymFirstHop;
			P_OVSF_Code = NocSF_F0_Fix[DataSymSecondHop - 1][SimParam->F1_OCC_Index];//guobaojuan,20180514

			for (l = SimParam->DataSymFirstHop; l < SimParam->DataSymNum; l++)//for each symbol of one slot
			{
				/*get OVSF code*/
				OVSF_Code.re = *P_OVSF_Code++;
				OVSF_Code.im = *P_OVSF_Code++;
				for (k = 0; k < SC_PER_RB; k++)
				{
					Temp.re = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].re - QAM_Op[0].im*PUCCH_ZC_Data[l][k].im) >> 1, 14);
					Temp.im = sat_fr1xN_bitwidth((QAM_Op[0].re*PUCCH_ZC_Data[l][k].im + QAM_Op[0].im*PUCCH_ZC_Data[l][k].re) >> 1, 14);

					PUCCH_ResOp[l][k].re = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.re - Temp.im*OVSF_Code.im) >> 13, 14);
					PUCCH_ResOp[l][k].im = sat_fr1xN_bitwidth((Temp.re*OVSF_Code.im + Temp.im*OVSF_Code.re) >> 13, 14);

				}
			}

		}
	}
	else
	{
		for (l = 0; l < SimParam->DataSymNum; l++)//for each symbol of one slot
		{
			for (k = 0; k < SC_PER_RB; k++)
			{
				PUCCH_ResOp[l][k].re = QAM_Op[l * SC_PER_RB + k].re << 9;//Q(14,5)
				PUCCH_ResOp[l][k].im = QAM_Op[l * SC_PER_RB + k].im << 9;
			}
		}

	}
}




